﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using XLua;
using Yoozoo.Framework.Managers;
using Yoozoo.Gameplay.City;
using Yoozoo.Gta.Common;

namespace Modules.Goto.Runtime
{
    /// <summary>
    /// 跳转遮罩类
    /// </summary>
    public class GotoMask : MonoBehaviour, ICanvasRaycastFilter
    {
        public bool m_downed = false;       // 是否点击
        public bool m_clickArea = false;    // 是否点击到指定区域
        public Transform m_target;          // 目标 UI或者3D 物体
        public bool m_force = false;        // 是否强制点击
        public GameObject m_targetButton;   // 点击目标按钮
        public bool bCliclEnable = true;
        public bool bWorldSpaceUI = false;  // 是不是3D UI 如果是3DUI 需要用当前主相机检查
        private int m_marchHudLayer = 0;
        public bool bClickAnyWhere = false; //判定任意点击都有效

        public int eventId = 0;// 内城点击事件id
        private LuaFunction eventLua;
        private Vector3 eventCheckPos = Vector3.zero;
        private GameObject eventDebugObj;
        private void Awake()
        {
            m_marchHudLayer = LayerMask.NameToLayer("MarchHud");
        }

        public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
        {
            return m_force;
        }

        public void ResetData()
        {
            m_downed = false;       // 是否点击
            m_clickArea = false;    // 是否点击到指定区域
            m_target = null;          // 目标 UI或者3D 物体
            m_targetButton = null;
        }

        /// <summary>
        /// 点击屏幕坐标
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public GameObject GetFirstPickGameObject(Vector2 position)
        {
            EventSystem eventSystem = EventSystem.current;
            PointerEventData pointerEventData = new PointerEventData(eventSystem);
            pointerEventData.position = position;
            //射线检测ui
            List<RaycastResult> uiRaycastResultCache = new List<RaycastResult>();
            eventSystem.RaycastAll(pointerEventData, uiRaycastResultCache);
            if (uiRaycastResultCache.Count > 0)
                return uiRaycastResultCache[0].gameObject;
            return null;
        }
        private LuaFunction onGotoClick;

        void Update()
        {
            if (onGotoClick == null)
            {
                onGotoClick = LuaManager.mainState.GetFunction("L_GoTo.onGotoClick");
            }
            
            if (bCliclEnable)
            {
                CheckMaskClick();
            }
        }

        void CheckMaskClick()
        {
            if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began))
            {
                bool isClickOption = false;
                bool is3DTarget = (m_target != null) && !(m_target is RectTransform);
#if (UNITY_ANDROID || UNITY_IPHONE) && !UNITY_EDITOR
            if (Input.touchCount > 0 && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#else
                if (EventSystem.current.IsPointerOverGameObject())
#endif
                {
                    isClickOption = true;
                    if (m_target != null)
                    {
                        //UI
                        if (m_target is RectTransform)
                        {
                            CheckClickUI();
                        }
                        else if (eventId > 0)
                        {
                            CheckClickCityEvent();
                        }
                        // 碰撞体
                        else
                        {
                            CheckClick3D();
                        }
                    }
                }
                else
                {
                    if (m_target != null)
                    {
                        if(is3DTarget)
                        {
                            isClickOption = true;
                            CheckClick3D();
                        }
                        else if (eventId > 0)
                        {
                            isClickOption = true;
                            CheckClickCityEvent();
                        }
                    }
                }
               
                if (isClickOption)
                {
                    ClickOption();
                }
            }
        }


        private void CheckClickUI()
        {
            bool bClickSelf = GetFirstPickGameObject(Input.mousePosition) == gameObject || !m_force;
            if (!bClickSelf)
            {
                Debug.Log("[GotoMask] | GetFirstPickGameObject is click other");
                return;
            }
            Camera camera = ResidentHandler.Inst.UICamera;
            if (RectTransformUtility.RectangleContainsScreenPoint(m_target as RectTransform, Input.mousePosition, camera))
            {
                Debug.Log("[GotoMask] | is raycast target by UICamera => " + m_target.name);
                m_clickArea = true;
            }
            if (m_targetButton != null)
            {
                if (RectTransformUtility.RectangleContainsScreenPoint(m_targetButton.transform as RectTransform, Input.mousePosition, camera))
                {
                    Debug.Log("[GotoMask] | is raycast m_targetButton by UICamera => " + m_targetButton.name);
                    m_clickArea = true;
                }
            }

            // 检测当前绑定的btn是WorldSpaceUI 
            bool isWorldSpaceUI = false;
            if (m_target)
            {
                isWorldSpaceUI = m_target.gameObject.layer == m_marchHudLayer;
            }
            if (m_targetButton)
            {
                isWorldSpaceUI = isWorldSpaceUI || m_targetButton.gameObject.layer == m_marchHudLayer;
            }

            if (bWorldSpaceUI || isWorldSpaceUI)
            {
                if (DynamicLayerMgr.inCityLod)
                {
                    camera = CityManager.Instance.mobileTouchCamera.GetComponent<Camera>();
                }
                else
                {
                    camera = WorldCameraManager.GetInstance().GetCamera();
                }

                if (RectTransformUtility.RectangleContainsScreenPoint(m_target as RectTransform, Input.mousePosition, camera))
                {
                    Debug.Log("[GotoMask] | is raycast target by mainCamera => " + m_target.name);
                    m_clickArea = true;
                }

                if (m_targetButton != null)
                {

                    if (RectTransformUtility.RectangleContainsScreenPoint(m_targetButton.transform as RectTransform, Input.mousePosition, camera))
                    {
                        Debug.Log("[GotoMask] | is raycast m_targetButton by mainCamera => " + m_targetButton.name);
                        m_clickArea = true;
                    }
                }
            }
        }

        private void CheckClick3D()
        {
            // 射线检测
            Camera camera = null;
            if (DynamicLayerMgr.inCityLod)
            {
                camera = CityManager.Instance.mobileTouchCamera.GetComponent<Camera>();
            }
            else
            {
                camera = WorldCameraManager.mainCamera;
            }
            var ray = camera.ScreenPointToRay(Input.mousePosition);
            RaycastHit[] hitInfos = Physics.RaycastAll(ray, camera.farClipPlane);
            for (int i = 0; i < hitInfos.Length; i++)
            {
                RaycastHit hitInfo = hitInfos[i];
                if (hitInfo.transform == m_target || (m_targetButton != null && hitInfo.transform == m_targetButton.transform))
                {
                    Debug.Log("[GotoMask] | is raycast 3D target => " + m_target.name);
                    m_clickArea = true;
                }
            }
        }

        private void CheckClickCityEvent()
        {
            Camera camera = null;
            if (DynamicLayerMgr.inCityLod)
            {
                camera = CityManager.Instance.mobileTouchCamera.GetComponent<Camera>();
            }
            else
            {
                camera = WorldCameraManager.mainCamera;
            }
            eventCheckPos = Input.mousePosition;
            Vector3 screenPos = camera.WorldToScreenPoint(m_target.transform.position);
            eventCheckPos.z = screenPos.z;
            Vector3 worldPos = camera.ScreenToWorldPoint(eventCheckPos);
            if (eventLua == null)
            {
                eventLua = LuaManager.mainState.GetFunction("L_GoTo.onCheckCityEventClick");
            }
            //if (eventDebugObj == null)
            //{
            //    eventDebugObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            //    eventDebugObj.name = "eventDebugObj";
            //}
            //Vector3 pos = eventDebugObj.transform.position;
            //eventDebugObj.transform.position = worldPos;
            if (eventLua != null)
            {
                object[] luaTable = eventLua.Call(worldPos.x, worldPos.z, eventId);
                bool isClick = luaTable.Length > 0 && luaTable[0] != null && (bool)(luaTable[0]);
                if (isClick)
                {
                    Debug.Log("[GotoMask] | is Click eventId => " + eventId);
                    m_clickArea = true;
                }
            }
        }

        public void ClickOption()
        {
            // 引导 存在点击对象才调用lua回调
            if (m_targetButton)
            {
                onGotoClick?.Call();
                // 引导 点击到指定位置调用对应按钮功能
                if (m_clickArea)
                {
                    // 强引导点击过后立刻把数据清理掉 防止多次点击
                    ResetData();
                    //ExecuteEvents.Execute(button, new PointerEventData(EventSystem.current), ExecuteEvents.pointerClickHandler);
                }
            }
            else if (bClickAnyWhere)
            {
                bClickAnyWhere = false;
                onGotoClick?.Call();
            }
        }

    }
}
